<?php

namespace App\Services\Game;

use App\Core\Traits\Numeral;
use App\Exports\Game\UserExport;
use App\Models\Game\Config\Currency;
use App\Services\Game\Config\CurrencyService;
use App\Services\Service;
use App\Services\Traits\DatabaseMysql;
use App\Models\Game\User\User;

class UserService extends Service
{
    use DatabaseMysql, Numeral;

    /**
     * 导出数据
     *
     * @param \Illuminate\Database\Eloquent\Builder $query
     * @param \Illuminate\Http\Request $request
     * @param bool $export
     * @return false|void
     */
    private function export($query, $request, bool $export)
    {
        if (!$export) {
            return false;
        }
        // 前端排序
        $this->makeOrderParam($request, $query);
        // 查询数据
        $query->with([
            'wallet','playerSlo:id,slo_model_id', 'playerFish:id,fish_model_id',
            'org:code,name', 'player:id,last_game_time,last_game_id'
        ]);
        // 导出文件
        UserExport::query($query)->setRequest($request)->download();
    }

    /**
     * 获取数据列表
     *
     * @param \Illuminate\Http\Request $request
     * @return \Illuminate\Database\Eloquent\Collection[]|int[]
     */
    public function getList($request, $export = false)
    {
        $query = User::query();

        // 筛选【平台】
        $this->makeWhereParamOrg($request, $query);
        // 筛选【访问控制】
        $this->makeWhereParamBits($request, 'access', $query);
        // 筛选【角色】
        $this->makeWhereParamBits($request, 'role', $query);
        // 筛选【搜索】
        $this->makeWhereParamSearch($request, $query);
        // 筛选【币种】
        $currencys = $request->input('currency', []);
        $currencystr = json_encode($currencys);
        $currencystr = str_ireplace(['"COIN'], '"CNY', $currencystr);
        $currencys = json_decode($currencystr, true);
        !empty($currencys) && $query->whereHas('wallet', function ($query)use($request, $currencys) {
            foreach ($currencys as $key=>$currency){
                if($key == 0){
                    $query->where('balances->'.$currency, '>', 0);
                }else{
                    $query->orWhere('balances->'.$currency, '>', 0);
                }
            }
        });

        // 导出数据
        $this->export($query, $request, $export);

        // 数据条数
        $total = (clone $query)->count();
        // 统计数据
        $stats = $this->getStats(clone $query, $request);
        // 排序分页
        $this->makeOrderParam($request, $query)->makePaginationParam($request, $query);
        // 查询数据
        $collection = $query->with([
            'wallet', 'playerSlo:id,slo_model_id', 'playerFish:id,fish_model_id',
            'org:code,name', 'player:id,last_game_time,last_game_id'
        ])->get();

        if($currencys){
            $collection->transform(function ($item)use($request, $currencys){
                $balances = [];
                foreach ($currencys as $currency){
                    if(isset($item['wallet']['balances'][$currency])) {
                        $balances[$currency] = $item['wallet']['balances'][$currency];
                    }
                }
                $item['wallet']['balances'] = $balances;
                return $item;
            });
        }

        return [
            $collection,
            $total,
            $stats
        ];
    }


    public function getStat($request, $export = false)
    {
        $query = User::query();

        // 筛选【平台】
        $this->makeWhereParamOrg($request, $query);
        // 筛选【访问控制】
        $this->makeWhereParamBits($request, 'access', $query);
        // 筛选【角色】
        $this->makeWhereParamBits($request, 'role', $query);
        // 筛选【搜索】
        $this->makeWhereParamSearch($request, $query);
        // 筛选【币种】
        $currencys = $request->input('currency', []);
        $currencystr = json_encode($currencys);
        $currencystr = str_ireplace(['"COIN'], '"CNY', $currencystr);
        $currencys = json_decode($currencystr, true);
        !empty($currencys) && $query->whereHas('wallet', function ($query)use($request, $currencys) {
            foreach ($currencys as $key=>$currency){
                if($key == 0){
                    $query->where('balances->'.$currency, '>', 0);
                }else{
                    $query->orWhere('balances->'.$currency, '>', 0);
                }
            }
        });

        // 导出数据
        $this->export($query, $request, $export);

        // 统计数据
        $stats = $this->getStats(clone $query, $request, 1000);

        return [
            $stats
        ];
    }

    /**
     * 搜索数据列表
     *
     * @param \Illuminate\Http\Request $request
     * @return \Illuminate\Database\Eloquent\Collection
     */
    public function search($request)
    {
        $query = User::query();
        // 筛选【平台】
        $this->makeWhereParamOrg($request, $query);

        return $query->with('org:code,name')
            ->where('account_id', 'like', $request->input('keyword') . '%')
            ->limit($this->getPageSize())
            ->get();
    }

    /**
     * 获取统计信息
     *
     * @param \Illuminate\Database\Eloquent\Builder $query
     * @return array
     */
    private function getStats($query, $request, $limit = 5)
    {
        $currencies = $request->input('currency', []);
        $currencystr = json_encode($currencies);
        $currencystr = str_ireplace(['"COIN'], '"CNY', $currencystr);
        $currencies = json_decode($currencystr, true);

//        empty($currencies) && $currencies = CurrencyService::create()->getAll()->toArray();
        empty($currencies) && $currencies = Currency::limit($limit)->get('currency')->values()->pluck('currency')->toArray();


        $selectRaws = [];
        foreach ($currencies as $currency){
            $selectRaws[] = "IFNULL(CAST(SUM(t_user_wallet.balances->'$.\"$currency\"') AS DECIMAL({$this->decimals()},{$this->precision()})),0) AS `$currency`";
        }
        // USD【合计】
        $rows = (clone $query)->getQuery()
            ->join('t_user_wallet', 't_user_wallet.id', 't_user.id')
            ->selectRaw(implode(',', $selectRaws))
            ->first();

        foreach ($rows as $key=>&$row){
            $row = rtrim(rtrim($row, '0'), '.');
            if($row == 0) unset($rows[$key]);
        }

        return $rows;
    }
}
